﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Collections;

namespace SharpShare.Storage.ApplePhotoLibrary {
    internal static class PropertyList {
        public static object Read(XmlReader reader) {
            if (!reader.ReadToFollowing("plist")) {
                throw new InvalidOperationException("Couldn't find element 'plist'.");
            }

            string version = reader.GetAttribute("version");

            if (version != "1.0") {
                throw new InvalidOperationException(string.Format("Unsuppported property list version '{0}'.", version));
            }
            
            reader.Read();
            reader.MoveToContent();

            object item = ReadItem(reader);

            return item;
        }

        private static object ReadItem(XmlReader reader) {
            while (reader.NodeType != XmlNodeType.Element) {
                if (!reader.Read()) {
                    return null;
                }
            }

            switch (reader.Name) {
                case "string":
                    return reader.ReadElementContentAsString();
                case "integer":
                    return reader.ReadElementContentAsInt();
                case "real":
                    return reader.ReadElementContentAsFloat();
                case "true":
                    reader.Skip();
                    return true;
                case "false":
                    reader.Skip();
                    return false;
                case "key": {
                        string name = reader.ReadElementContentAsString();
                        object value = ReadItem(reader);
                        return new DictionaryEntry(name, value);
                    }
                case "dict": {
                        Hashtable dict = new Hashtable();

                        reader = reader.ReadSubtree();
                        reader.ReadStartElement("dict");

                        for (; ; ) {
                            object item = ReadItem(reader);
                            if (item == null) {
                                break;
                            }

                            if (!(item is DictionaryEntry)) {
                                throw new InvalidOperationException("Expected dictionary entry.");
                            }

                            DictionaryEntry entry = (DictionaryEntry)item;
                            dict.Add(entry.Key, entry.Value);
                        }

                        return dict;
                    }
                case "array": {
                        ArrayList array = new ArrayList();

                        reader = reader.ReadSubtree();
                        reader.ReadStartElement("array");

                        for (; ; ) {
                            object item = ReadItem(reader);
                            if (item == null) {
                                break;
                            }
                            array.Add(item);
                        }

                        return array;
                    }
                default:
                    throw new InvalidOperationException(string.Format("Unexpected element '{0}'.", reader.Name));
            }

            throw new InvalidOperationException("Unexpected end of document.");
        }
    }
}
